﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WS.EKA.Business.Model;
using WS.EKA.Business.Utilty;
using Oracle.DataAccess.Client;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Configuration;

namespace WS.EKA.Business.Dal
{
    public class EventAccess
    {
        static IDB DBHelper = DBFactory.CreateBODB();
        public static List<EventSourceForUI> GetEventSourceWarnProportion()
        {
            var table = DBHelper.ExecuteDataTable(@"select SourceName,cast(count(Status) as number(12,0)) count,Status 
                                                    from(
                                                    select a.name SourceName,
                                                    case event_level 
                                                    when N'CRITICAL' then N'CRITICAL' 
                                                    when N'WARNING' then N'WARNING'
                                                    else N'WELL'
                                                    end 
                                                    as Status
                                                    from tb_eventsource a 
                                                    left join 
                                                      (select event_source,event_level from tb_event ev 
                                                      join tb_application app on( ev.app_code=app.app_code and app.IsActive='y' and (ev.event_source is not null and ev.event_source!=' ')  and ev.status='OPEN')
                                                      ) temp 
                                                    on temp.event_source=a.name  
                                                     )T  group by T.SourceName,T.Status
                                        ");
            var tempData = table.ToList<EventSourceTemp>();
            var dic = new Dictionary<string, EventSourceForUI>(8);
            foreach (var item in tempData)
            {
                if (!dic.ContainsKey(item.SourceName))
                    dic.Add(item.SourceName, new EventSourceForUI()
                    {
                        SourceName = item.SourceName,
                        Critical = item.Status == "CRITICAL" ? item.Count : 0,
                        Warning = item.Status == "WARNING" ? item.Count : 0
                    });
                else
                {
                    if (item.Status == "CRITICAL")
                        dic[item.SourceName].Critical = item.Count;
                    if (item.Status == "WARNING")
                        dic[item.SourceName].Warning = item.Count;
                }
            }

            ////获取所有类别
            //var sourceList = new List<string>(8);
            //using (var reader = DBHelper.ExecuteReader(@"select distinct name from tb_eventsource"))
            //{
            //    while (reader.Read())
            //    {
            //        sourceList.Add(reader[0].ToString());
            //    }
            //}

            //foreach (string source in sourceList)
            //{
            //    if (!dic.ContainsKey(source))
            //        dic.Add(source, new EventSourceForUI()
            //        {
            //            SourceName = source,
            //            Critical=0,
            //            Warning=0
            //        });
            //}

            return dic.Values.ToList();
        }

        public static List<AppStatus> GetOperationAppStatus()
        {
            return GetAppStatus("3");
        }

        public static List<AppStatus> GetFondationAppStatus()
        {
            return GetAppStatus("4");
        }

        public static List<AppStatus> GetOfficeAppStatus()
        {
            return GetAppStatus("1");
        }

        public static List<AppStatus> GetManageAppStatus()
        {
            return GetAppStatus("2");
        }

        private static List<AppStatus> GetAppStatus(string appType)
        {
            var parameters = new OracleParameter[1];
            parameters[0] = new OracleParameter("AppType", appType);
            var table = DBHelper.ExecuteDataTable(@"select app_name as Appname,app_type as AppType ,
                                                     case 
                                                     when CRITICAL>0
                                                     then N'CRITICAL'
                                                     when CRITICAL=0 and WARNING>0
                                                     then N'WARNING'
                                                     else N'WELL'
                                                     end
                                                     as Status
                                                     from
                                                     (
                                                    select a.app_name,a.app_type,
                                                    (select count(1) from tb_event b where b.app_code=a.app_code and b.status='OPEN' and b.event_level='CRITICAL' ) CRITICAL,
                                                    (select count(1) from tb_event b where b.app_code=a.app_code and b.status='OPEN' and b.event_level='WARNING' ) WARNING
                                                    from tb_application a where a.app_type=:AppType and a.IsActive='y'
                                                    )
                                        ", parameters);
            return table.ToList<AppStatus>();
        }

        public static List<EventSourcePie> GetEventSourceDistribute()
        {
            var table = DBHelper.ExecuteDataTable(@"select a.name as Category,cast(count(1) as number(9,0)) as Count 
                                                    from tb_eventsource a left join tb_event b on b.event_source=a.name
                                                    where b.status='OPEN' 
                                                    group by a.name");
            return table.ToList<EventSourcePie>();
        }

        public static EventListForUI GetEventList()
        {
            var obj = new EventListForUI();
            var t1 = Task.Factory.StartNew(() =>
                {
                    var parameters = new OracleParameter[1];
                    parameters[0] = new OracleParameter("EventListCount", int.Parse(ConfigurationManager.AppSettings["EventListCount"]));
                    var table = DBHelper.ExecuteDataTable(@"select cast(EventID as varchar2(50)) EventID,Type,AppName,IP,""DESC"",CreateDate,EventLevel from
                                                    (
                                                    select EventID,Type,AppName,IP,""DESC"",CreateDate,EventLevel from
                                                    (
                                                    select event_id EventID,ev.event_source Type,app.app_name AppName,host_id IP,
                                                    event_desc ""DESC"",ticket_id EventNo,begin_time CreateDate,event_level EventLevel  
                                                    from tb_event ev join tb_application app on((ev.event_source is not null and ev.event_source!=' ') and ev.app_code=app.app_code and app.IsActive='y')
                                                    where status='OPEN' and (event_level='CRITICAL' or event_level='WARNING') 
                                                        order by event_level asc, begin_time desc
                                                     )
                                                    )T where rownum<=:EventListCount
                                                    order by EventLevel asc, CreateDate desc
                                                    ", parameters);
                    obj.Data = table.ToList<EventData>();
                });

            var t2 = Task.Factory.StartNew(() =>
            {
                var reader = DBHelper.ExecuteReader(@"select sum(Critical) Critical,sum(Warn) Warn
                                                       from
                                                       (
                                                       select count(1) Critical,0 Warn  from tb_event  where status='OPEN' and event_level='CRITICAL' and (event_source is not null and event_source!=' ')
                                                       and exists( select * from  tb_application a where a.app_code= tb_event.app_code and a.IsActive='y')  
                                                       union
                                                       select 0,count(1) from tb_event  where status='OPEN' and event_level='WARNING' and (event_source is not null and event_source!=' ')
                                                       and exists( select * from  tb_application a where a.app_code= tb_event.app_code and a.IsActive='y')  
                                                       )"
                            );
                using (reader)
                {
                    while (reader.Read())
                    {
                        obj.Critical = Convert.ToInt64(reader[0]);
                        obj.Warn = Convert.ToInt64(reader[1]);
                    }
                }
            });
            Task.WaitAll(t1, t2);
            return obj;
        }

        [Conditional("DEBUG")]
        private static void GetFakeEventList(ref EventListForUI obj)
        {
            obj = new EventListForUI()
            {
                Critical = 123,
                Warn = 22,
                Data = new List<EventData>()
                {
                    new EventData()
                    {
                        AppName="OA",
                        CreateDate=DateTime.Now,
                        Desc="desc test",
                        EventID="123123",
                        EventLevel="Critical",
                        EventNo="Inc0000123",
                        IP="192.168.0.1",
                        Type="VSM_CPU_VM"
                    },
                     new EventData()
                    {
                        AppName="监控",
                        CreateDate=DateTime.Now,
                        Desc="desc test",
                        EventID="35345",
                        EventLevel="Warning",
                        EventNo="Inc0000123",
                        IP="192.168.0.1",
                        Type="NT_LOGICAL_DISKS"
                    },
                    new EventData()
                    {
                        AppName="HR",
                        CreateDate=DateTime.Now,
                        Desc="desc test",
                        EventID="35345",
                        EventLevel="Warning",
                        EventNo="Inc0000123",
                        IP="192.168.0.1",
                        Type="VSM_VM"
                    }
                }
            };
        }
    }
}
